package poker_server;

import java.util.*;
import java.io.*;
import ocsf.server.*;
import poker.*;

/**
 *
 * @author Matt
 */
public class PokerServer extends AbstractServer{

    final public static int DEFAULT_PORT = 5555;

    public PokerServer()
    {
        super(DEFAULT_PORT);
        setPort(DEFAULT_PORT);

        try
        {
            this.listen();
        }
        catch (IOException ex)
        {}

        engine = new PokerEngine(this);

	
        //new ServerFrame();
    }

    @Override
    protected void clientConnected(ConnectionToClient client) {

        if ((player1 != null) && (player2 != null) && (player3 != null) && (player4 != null))
        {
            sendMessage(client, "Game is full");
            try
            {
                client.close();
            }
            catch(IOException ex)
            {
               sendMessage(client,"Error closing connection");
            }
        }

        sendToAll("Client connecting: " + client);

        sendMessage(client, "Welcome to multiplayer texas hold 'em");

        if ( player1 == null )
            player1 = client;
        else if (player2 == null)
            player2 = client;
        else if (player3 == null)
            player3 = client;
        else
        {
            player4 = client;
        }
    }

    protected void clientDisconnected(ConnectionToClient client) {
	if (client == player1)
        {
            engine.removePlayer("player1");
            player1 = null;
        }
        else if (client == player2)
        {
            engine.removePlayer("player2");
            player2 = null;
        }
        else if (client == player3)
        {
            engine.removePlayer("player3");
            player3 = null;
        }
        else if (client == player4)
        {
            engine.removePlayer("player4");
            player4 = null;
        }
    }
    
    public void handleMessageFromClient(Object msg, ConnectionToClient client) {
        String player = "";

        if(client == player1)
            player = "player1";
        else if(client == player2)
            player = "player2";
        else if(client == player3)
            player = "player3";
        else player = "player4";

        if(msg instanceof Move)
            processMove((Move)msg, player, client);
        else
        {
            engine.setName(player, (String)msg);
            if(player4 != null)
            {
                sendToAll("Game is about to start");
                try
                {
                    Thread.currentThread().sleep(1000);
                }
                catch (Exception e)
                {
                    System.err.println("Error: handlemessagefromclient sleep");
                }
                engine.start();
            }
        }
    }

    private void processMove(Move move, String player, ConnectionToClient client)
    {
        try
        {
            engine.attemptMove(move, player);
            if(engine.getDone())
            {
                engine.calculateWinner(engine.getTable());
                engine.newHand();
            }
        }
        catch(PokerEngine.PlayOutOfTurnException ex) {
            sendMessage(client, "Not your turn");
        }
        catch(PokerEngine.BadMoveException ex) {
            sendMessage(client, "Not a valid move");
        }
        catch(PokerEngine.PlayWhenFoldedException ex) {
            sendMessage(client, "You have folded");
        }


    }

    public void sendToClient(String name, Object msg)
    {
        if(name.equals("player1"))
            sendMessage(player1, msg);
        else if(name.equals("player2"))
            sendMessage(player2, msg);
        else if(name.equals("player3"))
            sendMessage(player3, msg);
        else if(name.equals("player4"))
            sendMessage(player4, msg);
        else
            throw new RuntimeException("Unrecognized client in sendToClient");
    }


    private void sendMessage(ConnectionToClient client, Object message) {

        try {
            client.sendToClient(message);
        }
        catch(IOException ex){
            System.err.println("Error:SendMessage");
            System.err.println(ex);
        }
    }

    public void sendToAll(Object message) {
        if(player1 != null)
            sendMessage(player1, message);
        //else System.err.println("Error:SendToAllNullPlayer1");
        if(player2 != null)
            sendMessage(player2, message);
        //else System.err.println("Error:SendToAllNullPlayer2");
        if(player3 != null)
            sendMessage(player3, message);
        //else System.err.println("Error:SendToAllNullPlayer3");
        if(player4 != null)
            sendMessage(player4, message);
        //else System.err.println("Error:SendToAllNullPlayer4");
    }

    private PokerEngine engine;
    private ConnectionToClient player1;
    private ConnectionToClient player2;
    private ConnectionToClient player3;
    private ConnectionToClient player4;
}
